
#include "GlutTimer.h"

#include <ctime>
#include <glut.h>


/// TimerAccounting
void TimerAccounting::regTimer(GlutTimer* pTimer)
{
    if (!pTimer)
        return;
    pTimer->id = generateId();
    store.insert(std::make_pair(pTimer->id, pTimer));
}

void TimerAccounting::unregTimer(GlutTimer* pTimer)
{
    if (!pTimer)
        return;

    store.erase(pTimer->id);
}

GlutTimer* TimerAccounting::getTimer(int id)
{
    GlutTimer* pTimer = 0;
    if (store.end() != store.find(id))
        pTimer = store[id];

    return pTimer;
}

int TimerAccounting::generateId()
{
    int id;
    srand(static_cast<unsigned int>(time(NULL)));
    while (store.end() != store.find(id = rand()));
    return id;
}

/// GlutTimer
TimerAccounting GlutTimer::tmrAcnt;

GlutTimer::GlutTimer() :  
    timeout(0), 
    bIsRunning(false),
    bSingleShot(false),
    id(0)
{
    tmrAcnt.regTimer(this);
}

GlutTimer::~GlutTimer()
{
    tmrAcnt.unregTimer(this);
}

void GlutTimer::setInterval(int millis) 
{
    timeout = millis;
}

void GlutTimer::start()
{
    bIsRunning = true;
    glutTimerFunc(timeout, GlutTimerFunction, id);
}

void GlutTimer::stop()
{
    bIsRunning = false;
}

bool GlutTimer::isRunning() const 
{
    return bIsRunning;
}

void GlutTimer::setSingleShot(bool b)
{
    bSingleShot = b;
}

void GlutTimer::GlutTimerFunction(int id)
{
    GlutTimer* pTimer = tmrAcnt.getTimer(id);
    if (pTimer && pTimer->bIsRunning) {
        pTimer->onTimer();
        if (!pTimer->bSingleShot)
            pTimer->start();
    }
}






